home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / comm / tcp / wu_ftpd_37_21.lha / wu-ftpd / src / fnmatch.c < prev    next >
C/C++ Source or Header  |  1994-08-08  |  4KB  |  158 lines

  1. /*
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Guido van Rossum.
  7.  *
  8.  * Redistribution and use in source and binary forms are permitted provided
  9.  * that: (1) source distributions retain this entire copyright notice and
  10.  * comment, and (2) distributions including binaries display the following
  11.  * acknowledgement:  ``This product includes software developed by the
  12.  * University of California, Berkeley and its contributors'' in the
  13.  * documentation or other materials provided with the distribution and in
  14.  * all advertising materials mentioning features or use of this software.
  15.  * Neither the name of the University nor the names of its contributors may
  16.  * be used to endorse or promote products derived from this software without
  17.  * specific prior written permission.
  18.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  19.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  20.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  21.  */
  22.  
  23. #if defined(LIBC_SCCS) && !defined(lint)
  24. static char sccsid[] = "@(#)fnmatch.c    5.3 (Berkeley) 6/23/90";
  25.  
  26. #endif /* LIBC_SCCS and not lint */
  27.  
  28. /*
  29.  * Function fnmatch() as proposed in Posix 1003.2 B.6 (rev. 9).
  30.  * Compares a filename or pathname to a pattern.
  31.  */
  32.  
  33. #ifndef AMIGA
  34. #include "../src/config.h"
  35. #else
  36. #include "config.h"
  37. #endif
  38.  
  39. #include <string.h>
  40. #include <ctype.h>
  41.  
  42. /* fnmatch function */
  43. #ifndef FNM_PATHNAME
  44. #define    FNM_PATHNAME    0x01    /* match pathnames, not filenames */
  45. #endif
  46.  
  47. #ifndef FNM_QUOTE
  48. #define    FNM_QUOTE    0x02        /* escape special chars with \ */
  49. #endif
  50.  
  51. #ifndef FNM_NOCASE
  52. #define    FNM_NOCASE    0x04        /* case insensitive match */
  53. #endif
  54.  
  55. #define    EOS    '\0'
  56.  
  57. static char *
  58. rangematch(register char *pattern, register char test)
  59. {
  60.     register char c,
  61.       c2;
  62.     int negate,
  63.       ok;
  64.  
  65.     if ( (negate = (*pattern == '!')) )
  66.         ++pattern;
  67.  
  68.     /* TO DO: quoting */
  69.  
  70.     for (ok = 0; (c = *pattern++) != ']';) {
  71.         if (c == EOS)
  72.             return (NULL);        /* illegal pattern */
  73.         if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') {
  74.             if (c <= test && test <= c2)
  75.                 ok = 1;
  76.             pattern += 2;
  77.         } else if (c == test)
  78.             ok = 1;
  79.     }
  80.     return (ok == negate ? NULL : pattern);
  81. }
  82.  
  83. int
  84. fnmatch(register char *pattern, register char *string, int flags)
  85. {
  86.     register char c;
  87.     char test;
  88.  
  89. /*
  90.     static char *rangematch();
  91. */
  92.  
  93.     for (;;)
  94.         switch (c = *pattern++) {
  95.         case EOS:
  96.             return (*string == EOS);
  97.         case '?':
  98.             if ( ((test = *string++) == EOS || test == '/') && 
  99.                    (flags & FNM_PATHNAME))
  100.                 return (0);
  101.             break;
  102.         case '*':
  103.             c = *pattern;
  104.             /* collapse multiple stars */
  105.             while (c == '*')
  106.                 c = *++pattern;
  107.  
  108.             /* optimize for pattern with * at end or before / */
  109.             if (c == EOS)
  110.                 if (flags & FNM_PATHNAME)
  111.                     return (!strchr(string, '/'));
  112.                 else
  113.                     return (1);
  114.             else if (c == '/' && flags & FNM_PATHNAME) {
  115.                 if ((string = (char *) strchr(string, '/')) == (char *) NULL)
  116.                     return (0);
  117.                 break;
  118.             }
  119.             /* general case, use recursion */
  120.             while ((test = *string) != EOS) {
  121.                 if (fnmatch(pattern, string, flags))
  122.                     return (1);
  123.                 if (test == '/' && flags & FNM_PATHNAME)
  124.                     break;
  125.                 ++string;
  126.             }
  127.             return (0);
  128.         case '[':
  129.             if ( ((test = *string++) == EOS || test == '/') && 
  130.                   (flags & FNM_PATHNAME) )
  131.                 return (0);
  132.             if ((pattern = rangematch(pattern, test)) == NULL)
  133.                 return (0);
  134.             break;
  135.         case '\\':
  136.             if (flags & FNM_QUOTE) {
  137.                 if ((c = *pattern++) == EOS) {
  138.                     c = '\\';
  139.                     --pattern;
  140.                 }
  141.                 if (c != *string++)
  142.                     return (0);
  143.                 break;
  144.             }
  145.             /* FALLTHROUGH */
  146.         default:
  147.             if (flags & FNM_NOCASE) {
  148.                 if (tolower(c) != tolower(*string))
  149.                     return (0);
  150.             } else {
  151.                 if (c != *string)
  152.                     return (0);
  153.             }
  154.             string++;
  155.             break;
  156.         }
  157. }
  158.